import { login, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { anyRoutes, resetRouter, asyncRoutes, constantRoutes } from "@/router";
import router from "@/router";

const getDefaultState = () => {
  return {
    // 获取token
    token: getToken(),
    // 存储用户信息
    name: "",
    avatar: "",
    // 菜单标记
    routes: [],
    roles: [],
    buttons: [],
    // 项目中已有的异步路由，与服务器返回的标记信息进行对比，得到的最终应显示的路由
    resultAsyncRoutes: [],
    // 用户最终需要展示的全部路由
    resultAllRoutes: [],
  };
};

const state = getDefaultState();

// 唯一修改state的地方
const mutations = {
  // 重置state
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  // 存储state
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  // 存储用户信息
  SET_USERINFO: (state, userInfo) => {
    state.name = userInfo.name;
    state.avatar = userInfo.avatar;
    state.routes = userInfo.routes;
    state.roles = userInfo.roles;
    state.buttons = userInfo.buttons;
  },
  // 最终计算出的异步路由
  SET_RESULTASYNVROUTES: (state, asyncRoutes) => {
    state.resultAsyncRoutes = asyncRoutes;
    // 计算出当前用户所要展示的所有路由
    state.resultAllRoutes = constantRoutes.concat(
      state.resultAsyncRoutes,
      anyRoutes
    );
    // 给路由器添加新的路由
    router.addRoutes(state.resultAllRoutes);
  },
};

// 对比路由
const computedAsyncRoutes = (asyncRoutes, routes) => {
  // 过滤出当前用户需要展示的异步路由
  return asyncRoutes.filter((item) => {
    // 如果 routes数组中没有该item.name
    if (routes.indexOf(item.name) != -1) {
      // 遍历各子级路由，使用递归
      if (item.children && item.children.length) {
        // 如果该item有子级路由，则将其子级路由继续与 routes进行对比
        item.children = computedAsyncRoutes(item.children, routes);
      }
      return true;
    }
  });
};

const actions = {
  // 登录
  // 使用 async和 await替代 .then
  async login({ commit }, userInfo) {
    // 解构出用户名与密码
    const { username, password } = userInfo;
    let result = await login({ username: username.trim(), password: password });
    // 使用 mock数据时，成功时返回 20000
    if (result.code === 20000) {
      // vuex存储token
      commit("SET_TOKEN", result.data.token);
      // 本地存储持久化token
      setToken(result.data.token);
      return "OK";
    } else {
      return Promise.reject(new Error(fail));
    }
  },

  // get user info
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token)
        .then((response) => {
          // data是用户信息，包括用户的name，avatar，
          // 以及routes——用户可以访问的路由组成的数组；roles用户角色；button用户使用按钮的权限
          const { data } = response;
          // vuex存储用户的全部信息
          commit("SET_USERINFO", data);
          commit(
            "SET_RESULTASYNVROUTES",
            computedAsyncRoutes(asyncRoutes, data.routes)
          );
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token)
        .then(() => {
          removeToken(); // must remove  token  first
          resetRouter();
          commit("RESET_STATE");
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

  // remove token
  resetToken({ commit }) {
    return new Promise((resolve) => {
      removeToken(); // must remove  token  first
      commit("RESET_STATE");
      resolve();
    });
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
